package com.cloud.cop.impl;

import org.springframework.beans.BeanUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.support.WebRequestDataBinder;
import org.springframework.web.context.request.WebRequest;

import com.cloud.cop.CopRequest;
import com.cloud.cop.CopResponse;
import com.cloud.cop.CopServiceContext;
import com.cloud.cop.CopServiceHandler;
import com.cloud.cop.CopServiceMethodAdapter;
import com.cloud.cop.response.ErrorCopResponse;
import com.cloud.cop.response.ServiceErrorResponse;
import com.cloud.cop.validation.CopValidator;
import com.cloud.cop.validation.DefaultCopValidator;
import com.cloud.cop.validation.MainError;
import com.cloud.cop.validation.MainErrorType;
import com.cloud.cop.validation.MainErrors;

/**
 * 统一调用服务实现类
 * @author mayh
 *
 */
public class DefaultCopServiceMethodAdapter implements CopServiceMethodAdapter {

	private FormattingConversionService conversionService;
	private Validator validator;
	private CopValidator copValidator = new DefaultCopValidator();
	/**
	 * 
	 * 调用服务的方法
	 * 
	 */
	public CopResponse invokeServiceMethod(CopServiceContext context) {
		try{
		//获得服务的执行者
		CopServiceHandler copServiceHandler = context.getCopServiceHandler();
		//进行错误验证
		MainError mainError  = preProcess(context);
		if(mainError!=null){
			return new ErrorCopResponse(mainError);
		}
		if(copServiceHandler.isMethodHaveParameters()){
			return (CopResponse)copServiceHandler.getMethod().invoke(copServiceHandler.getHandler(), context.getCopRequest());
		}else {
			return (CopResponse)copServiceHandler.getMethod().invoke(copServiceHandler.getHandler());
		}
		}catch(Exception e){
			e.printStackTrace();
			return new ErrorCopResponse(MainErrors.getErrors(MainErrorType.SAVE_FAIL, context.getLocale()));
		}
		
//		return null;
	}

	public MainError preProcess(CopServiceContext context){
		//判断请求的方法是否有效
		if(context.getCopServiceHandler()==null)
			return MainErrors.getErrors(MainErrorType.INVALID_METHOD, context.getLocale());
		BindingResult bindResult = doBind(context.getWebRequest(),context.getCopServiceHandler().getRequestType());
		context.setCopRequest((CopRequest)bindResult.getTarget());
		context.setAllErrors(bindResult.getAllErrors());
		//验证数据的有效性
		MainError mainError = copValidator.validate(context);
		return mainError;
	}
	
	public BindingResult doBind(WebRequest webRequest,Class<? extends CopRequest> copRequest){
		Object bindObject = BeanUtils.instantiateClass(copRequest);
		WebRequestDataBinder dataBinder = new WebRequestDataBinder(bindObject,"bindObject");
		dataBinder.setConversionService(getConversionService());
		dataBinder.setValidator(getValidator());
		dataBinder.bind(webRequest);
		//spring 会根据注解对相关属性进行验证
		dataBinder.validate();
		return dataBinder.getBindingResult();
	}
	
	private ConversionService getConversionService(){
		if(this.conversionService==null){
			FormattingConversionServiceFactoryBean serviceFactoryBean = new FormattingConversionServiceFactoryBean();
            serviceFactoryBean.afterPropertiesSet();
            this.conversionService = serviceFactoryBean.getObject();
		}
		return this.conversionService;
	}
	
	private Validator getValidator(){
		if(this.validator==null){
			LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
            localValidatorFactoryBean.afterPropertiesSet();
            this.validator = localValidatorFactoryBean;
		}
		return this.validator;
	}
}
